package com.guaoran.interview.in23.string;

import javax.sound.midi.Soundbank;
import java.rmi.MarshalledObject;

/**
 * @author : 孤傲然
 * @description : String 类
 * @date :2019/10/22 20:15
 */
public class StringDemo {
    public static void main(String[] args) {

        /**
         * String 创建的时候会首先去 字符串常量池中查看是否存在对象，
         * 1. 如果不存在，会进行创建一个对象放到常量池中，并会复制到堆中
         *      因此 在s1创建的时候会创建一个对象到常量池，
         *      所以 后面所有的 相同值的 `intern()` 都等于 s1 ，且s1 等于 s1.intern()
         *      而对于 new 的对象，他们的常量池的值是相同的，但是地址不同，
         *      所以 s0 != s1,但是s0.intern() == s1.intern()==s1
         * 2. 如果存在
         *      如果是直接赋值，则地址和常量池都相同 即：s1==s11==s1.intern()==s11.intern();
         *      如果是 new  则 地址不相同，而常量池相同 即：s0 != s1,但是s0.intern() == s1.intern()==s1
         *      如果是 变量拼接，底层是StringBuilder.append, 这里有个特殊情况，如果拼接的变量全部是 final 修饰的，这里采用的是 赋值
         *      如果是 值拼接，底层是 赋值
         */

        String s0 = new String("hello world");
        String s1 = "hello world";
        String s11 = "hello world";
        System.out.println(s1!=s0 && s1==s0.intern() && s1.intern()==s0.intern());//true
        System.out.println(s1==s11 && s1.intern()==s11.intern() && s1==s11.intern() && s1==s1.intern());//true


        String s2 = new String("hello world");
        System.out.println(s0 != s1 && s0 != s2 && s0 != s2 && (s0.intern() == s1 && s1 == s2.intern()) && s1 == s1.intern());//true

        // 拼接采用的是 StringBuilder.append
        String s3 = "hello";
        String s4 = " world";
        String s5 = s3 + s4;
        System.out.println(s1!=s5 && s0!=s5 && s2!=s5 && s1.intern()==s5.intern());//true


        String s6 = "hello"+" world";
        System.out.println(s6!=s0 && s6!=s2 && s6==s1 && s6.intern() == s1);//true

        // 拼接采用的是 StringBuilder.append
        String s7 = "hello"+s4;
        System.out.println(s7 != s1 && s7.intern() == s1);// true


        // 如果相拼接的变量都是 final 修饰的，则采用的是赋值
        final String s8 = "hello";
        final String s9 = " world";
        String s10 = s8 + s9;
        System.out.println(s1==s10 && s1.intern() == s10.intern() && s1 == s10.intern());//true

        String s = s3.concat(s4);
        System.out.println(s1!=s && s1 == s.intern() && s1.intern() == s.intern());//true

    }
}
